(section
 :title [Opening the toy box]
 (p [Let's build ourself a little toy box for us to play around with.
     Enter the following at your Guile REPL:])

 (frame
  (prog :line #f
   "(define toy-box '(robot teddy-bear doll-with-comb toy-soldier))"))

 (p [If we forget what's inside our toy box, we can always look inside it.])

 (frame
  (prog :line #f
        "scheme@(guile-user)> toy-box
;; => (robot teddy-bear doll-with-comb toy-soldier)"))

 (p [Our friend ,(code "toy-box") here is a variable, and the information
       it references is called a "list", and lists are at the heart of
       Scheme (and indeed Lisp, which stands for "list processing", which
       Scheme is a variant of).
     We can verify that it is indeed a list:])

 (frame
  (prog :line #f
        "scheme@(guile-user)> (list? toy-box)
;; => #t"))

 (p [And indeed it is!])

 (p [Of course, the fun of the toy box is not the box itself, but the toys.
     So, let's pull out the first toy from the box:])

 (frame
  (prog :line #f
        "scheme@(guile-user)> (car toy-box)
;; => robot"))

 (p [That looks like the toy closest to the top of our box indeed.
     But why is that command called ,(code "car")?
     We weren't trying to pull a toy car from the box!
     "car" is a term with some history in lisps (it stands for
       "Content Address Register") but that history is not important
       to us at the very moment.
     For now, every time you see ,(code "car"), you can think of it as meaning
       "first".])

 (p [Of course, there are more toys in the box than just that robot.
     What's under the robot in the box?])

 (frame
  (prog :line #f
        "scheme@(guile-user)> (cdr toy-box)
;; => (teddy-bear doll-with-comb toy-soldier)"))

 (p [Another strange command... ,(code "cdr")!
     ,(code "cdr") is prounounced "could-er" (and also is a historical name,
       standing for "Content Decrement Register", which is again not
       important at the moment).
     For now, every time you see ,(code "cdr"), you can think of it as
       meaning "rest", giving you the rest of the list.])

 (p [We can see that at the top of the list returned with "cdr"
       is a nice looking teddy-bear.
     Can we pull that off the top?
     Indeed, we can by nesting the commands!])

 (frame
  (prog :line #f
        "scheme@(guile-user)> (car (cdr toy-box))
;; => teddy-bear"))
  
 (p [Horray!
     What a nice looking teddy-bear.])

 (p [One thing we can notice from the above is that we nested the call to
       cdr inside the call to car.
     We can understand how this works by doing the substitution
       manually:])

 (frame
  (source :language scheme
          (prog :line #f
           (string-join
            '("(car (cdr toy-box))"
              ";; Substitute in toy-box"
              "(car (cdr '(robot teddy-bear doll-with-comb toy-soldier)))"
              ";; Pull out the rest of the list via cdr"
              "(car '(teddy-bear doll-with-comb toy-soldier))"
              ";; Pull the first item off the top with car"
              "'teddy-bear")
            "\n"))))

 (p [This is how a lot of Guile/Scheme/Lisp looks:
       expressions nested inside other expressions.
     The parentheses help you understand the beginning and end of an
       expression.
     For much of the programming you will do with Guile, you can figure
       out what's going on by doing the substitutions in your head like
       above.
     (Not everything works via substitution, but discussing that is
       beyond the scope of this tutorial!)])

 (p [(There are other, easier to read ways to pull out items from a list
        (or toys from a toybox).
      We will get to them later.)])

 (p [What if we want to add a toy to our toybox?
     Luckily we have a little friend named ,(code "cons"), which is used
       to construct (or add to) lists.
     Let's cons a new toy to our toybox now!])

 (frame
  (prog :line #f
        "scheme@(guile-user)> (cons 'bouncy-ball toy-box)
;; => (bouncy-ball robot teddy-bear doll-with-comb toy-soldier)"))

 (p [It's so nice to see that bouncy-ball with its toy friends!
     But wait, this is surprising:])

 (frame
  (prog :line #f
        "scheme@(guile-user)> toy-box
;; => (robot teddy-bear doll-with-comb toy-soldier)"))

 (p [Huh?
     When we ran cons, we got back a new list of toys that included
       our bouncy-ball, but when we look back inside of toy-box, we
       see it isn't there!
     This is on purpose (and is actually a feature): when we used cons,
       we got back a new list with our old list attached at the end.
     It didn't change our old list to do this... changing our old list
       mean that we "mutated" it.
     (code "toy-box") is a variable, and it still points at our original toy box
       list.])

 (p [Suppose we did want to actully change what toy-box means and have
       it point to something else.
     We could do this.
     Guile has a command named ,(code [set!]) which will let you
       change the value of a variable we already defined.
     Let's try it:])

 (frame
  (prog :line #f
        "scheme@(guile-user)> (set! toy-box (cons 'bouncy-ball toy-box))
scheme@(guile-user)> toy-box
;; => (robot teddy-bear doll-with-comb toy-soldier)"))

 ;; TODO: Move this part to part two of the intro to procedures bit?
 (p [This seems rather convenient!
     And sometimes, it is.
     Unfortunately, assignment and mutation can sometimes cause unexpected
       and unpleasant surprises for us.
     Imagine we were running a program with many friends running around our
       playground at once.
     Our friend Jessica may hear that there's a robot in the box from her
       friend Aaron, and so she may go to retrieve it, but in-between that
       maybe we took the toy out of the box to play with, and Jessica will
       become very confused when she opens the box and doesn't see the
       robot.
     (Maybe she will even think that Aaron lied to her, though of course, we
       really didn't mean to cause that kind of mistake, we just wanted
       our robot!)
     Computer programs run into these same kinds of issues and often times
       have less ideas on what to do when things unexpectedly change around
       them than even we might, and this can lead to all sorts of problems.
     We won't go into details, but procedures that might cause tricky behavior
       like this are said to have "side effects", and in Guile (and Scheme
       generally) the convention is to label these with an exclaimation mark.
     So when you see the explaination mark at the end of ,(code "set!")
       remember that someone is shouting, "this has a side effect, be careful!"])
 
 (p [The good news though is that Guile provides both datastructures that do
       and don't require visible side effects.
     When it comes to lists, you can mutate them, but unless you really need
       to, you probably don't want to or have to!])

 (p [We'll come back to lists a bit more towards the end of the chapter.
     For now, there are some other fun types of data to play with.]))

(section
 :title [Simple types of toys]

 (p [So far we've worked with two types of data: lists and symbols.
     Of course, there are a lot of other types of data out there!
     But since we've seen symbols, let's start with them.
     (We'll get more into lists (and other ways to group information
       together)later.)])

 (p [All the toys that were in our box were symbols.
     We can create a symbol very easily:])

 (frame
  (prog :line #f
        "scheme@(guile-user)> 'race-car
;; => race-car"))

 (p [Symbols are used to stand in for ideas.
     Sometimes lisp programmers use them as "keys" to look up information,
       and lisp programs are technically themselves made mostly out of
       lists and symbols!
     You can test if two symbols are the same with ,(code "eq?"):])

 (frame
  (prog :line #f
        "scheme@(guile-user)> (eq? 'apple 'apple)
;; => #t
scheme@(guile-user)> (eq? 'apple 'orange)
;; => #f"))

 (p [Hey wait, what are those ,(code "#t") and ,(code "#f") things?
     Good question!
     These are called "booleans".
     In Guile, ,(code "#t") stands for "true" and ,(code "#f") stands
       for "false".
     Though you should know: in Guile everything that isn't ,(code "#f")
       is considered to be true!])

 (p [It would be nice if we could work with numbers.
     For example, we might like to be able to count how many toys are
       in our toy box.])

 (frame
  (prog :line #f
        "scheme@(guile-user)> (length toy-box)
;; => 4"))

 (p [The number we got back is an integer, in other words a whole number
       (which can be positive or negative).
     It's fun to play with integers!])

 ;; @@: Mixing comments and the ";; => foo" style is clearly not nice,
 ;;   as evidenced here...
 (frame
  (prog :line #f
        ";; Since Guile uses lisp-style \"prefix notation\", we write
;; \"8 + 2\" like (+ 8 2)
scheme@(guile-user)> (+ 8 2)
;; => 10
;; Multiplication looks similar:
scheme@(guile-user)> (* 6 10)
;; => 60
;; We can include multiple arguments to add or multiply many things at once:
scheme@(guile-user)> (+ 1 2 3)
;; => 6
;; And of course we can combine together math expressions
scheme@(guile-user)> (* (+ 1 2 3) 10)
;; => 60"))

 (p [Integers aren't the only kinds of numbers... Guile also has "rational"
       numbers (like fractions) and floating point numbers, or "inexact"
       numbers.
     Unlike in some other languages, Guile tries to keep numbers exact until
       you need to convert them to an inexact form.
     This makes Guile very nice for all sorts of number games!])

 (frame
  (prog :line #f
        ";; Floating point (inexact) numbers
scheme@(guile-user)> .4
;; => 0.4
;; We can enter rational numbers by hand
scheme@(guile-user)> 2/3
;; => 2/3
;; If we divide, we get back rational numbers
scheme@(guile-user)> (/ 2 3)
;; => 2/3
;; ... unless we choose to convert them to inexact form!
scheme@(guile-user)> (exact->inexact (/ 2 3))
;; => 0.6666666666666666"))

 (p [There are more number types available in Guile, but we'll let
       you read the manual to find out more about them.])

 (p [It would be nice to be able to describe our toys to someone.
     What can we use?
     It would be awkward to use symbols to say a whole sentence.
     We would like to be able to say something using a data type
       more befitting our words.
     Of course, words and sentences are made of letters, and in
       Guile, we call those "characters".
     Here is a list of characters:])
 
 (frame
  (prog :line #f
        "scheme@(guile-user)> '(#\\a #\\b #\\c #\\d #\\e #\\f #\\g)
;; => (#\\a #\\b #\\c #\\d #\\e #\\f #\\g)")) 

 (p [Well, talking to our friends letter by letter sounds very painful.
     Luckily, we have a nice type that deals with text called
       "strings", which "string together" a series of characters.
     And they are very easy to use!])

 (frame
  (prog :line #f
        "scheme@(guile-user)> \"abcdefg\"
;; => \"abcdefg\"
scheme@(guile-user)> (string->list \"abcdefg\")
;; => (#\\a #\\b #\\c #\\d #\\e #\\f #\\g)
scheme@(guile-user)> \"our teddy bear is very fuzzy\"
;; => \"our teddy bear is very fuzzy\"
scheme@(guile-user)> (string-join '(\"hop\" \"skip\" \"jump\")
                                  \" and a \")
;; => \"hop and a skip and a jump\"")) 

 (p [Those are some interesting kinds of toys to play with.
     Now it's time to learn how to breathe some life into them.]))

